﻿using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;
using System.Threading.Tasks;

namespace Skywave.Social
{
    [DataContract]
    public class Profile
    {
        [DataMember]
        public string Name { get; set; }

        [DataMember]
        public string FirstName { get; set; }

        [DataMember]
        public string LastName { get; set; }

        [DataMember]
        public string ProviderAccessToken { get; set; }

        [DataMember]
        public List<string> Emails { get; set; }

        [DataMember]
        public byte[] PictureBytes { get; set; }

        [DataMember]
        public SocialProviders Provider { get; set; }

        [DataMember]
        public string ProviderId { get; set; }

        public static SocialProviders? GetSocialProviderByName(string providerName)
        {
            SocialProviders? r = null;
            switch (providerName.Trim().ToLower())
            {
                case "facebook":
                    r = SocialProviders.Facebook;
                    break;
                case "microsoft":
                    r = SocialProviders.Microsoft;
                    break;
                case "google":
                    r = SocialProviders.Google;
                    break;
                default:
                    break;
            }
            return r;
        }
        public static async Task<Profile> Create(string providerName, string provider_AccessToken)
        {
            SocialProviders? provider = GetSocialProviderByName(providerName);
            if (provider != null)
                return await Create(provider.Value, provider_AccessToken);
            else
                return null;
        }
        public static async Task<Profile> Create(SocialProviders provider, string provider_AccessToken, bool includePicture = true, int retryCount = 2)
        {
            Profile r = null;
            try
            {
                if (!string.IsNullOrWhiteSpace(provider_AccessToken))
                {
                    r = new Profile();
                    r.Provider = provider;
                    r.ProviderAccessToken = provider_AccessToken;
                    // JSON Data
                    string json_Url = "";
                    switch (provider)
                    {
                        case SocialProviders.Facebook:
                            json_Url = string.Format("https://graph.facebook.com/me?access_token={0}", provider_AccessToken);
                            break;
                        case SocialProviders.Microsoft:
                            json_Url = string.Format("https://apis.live.net/v5.0/me/?method=GET&access_token={0}", provider_AccessToken);
                            break;
                        case SocialProviders.Google:
                            json_Url = string.Format("https://www.googleapis.com/oauth2/v3/userinfo?access_token={0}", provider_AccessToken);
                            break;
                        default:
                            throw new ArgumentException("Provider");
                    }
                    string json_Data = null;
                    Net.HttpWebRequestHelper httpWRH = new Net.HttpWebRequestHelper();
                    var q1_json_Data = await httpWRH.Download<string>(json_Url, retryCount);
                    if (!string.IsNullOrWhiteSpace(q1_json_Data))
                        json_Data = q1_json_Data.ToString();
                    else
                        return null;
                    //
                    string p_Url = "";
                    JObject json_Object = JObject.Parse(json_Data);
                    switch (provider)
                    {
                        case SocialProviders.Facebook:
                            r.ProviderId = (string)json_Object["id"];
                            r.Name = (string)json_Object["name"];
                            r.FirstName = (string)json_Object["first_name"];
                            r.LastName = (string)json_Object["last_name"];
                            r.Emails = new List<string>() { (string)json_Object["email"] };
                            break;
                        case SocialProviders.Microsoft:
                            r.ProviderId = (string)json_Object["id"];
                            r.Name = (string)json_Object["name"];
                            r.FirstName = (string)json_Object["first_name"];
                            r.LastName = (string)json_Object["last_name"];
                            r.Emails = new List<string>();
                            foreach (var fe1 in json_Object["emails"].Children())
                            {
                                if (fe1 is JProperty)
                                    if ((fe1 as JProperty).Value is JValue)
                                    {
                                        var jV1 = ((fe1 as JProperty).Value as JValue).Value;
                                        if (jV1 != null && !string.IsNullOrWhiteSpace(jV1.ToString()) && !r.Emails.Contains(jV1.ToString()))
                                            r.Emails.Add(jV1.ToString());
                                    }
                            }
                            break;
                        case SocialProviders.Google:
                            r.ProviderId = (string)json_Object["sub"];
                            r.Name = (string)json_Object["name"];
                            r.FirstName = (string)json_Object["given_name"];
                            r.LastName = (string)json_Object["family_name"];
                            r.Emails = new List<string>() { (string)json_Object["email"] };
                            //
                            p_Url = (string)json_Object["picture"];
                            break;
                        default:
                            break;
                    }
                    // Profile Picture
                    switch (provider)
                    {
                        case SocialProviders.Facebook:
                            p_Url = string.Format("http://graph.facebook.com/{0}/picture?type=normal", r.ProviderId);
                            break;
                        case SocialProviders.Microsoft:
                            p_Url = string.Format("https://apis.live.net/v5.0/me/picture/?method=GET&access_token={0}", provider_AccessToken);
                            break;
                        case SocialProviders.Google:
                            break;
                        default:
                            break;
                    }
                    //
                    if (includePicture)
                    {
                        var q1_PictureBytes = await httpWRH.Download<byte[]>(p_Url, retryCount);
                        if (q1_PictureBytes != null)
                            r.PictureBytes = (byte[])q1_PictureBytes;
                    }
                }
            }
            catch (Exception ex1)
            {
                r = null;
                Debug.WriteLine("Profile -> Create, Unknown exception:\n" + ex1.ToString());
            }
            //
            return r;
        }

    }
}
